package android.slc.base.api.slc.callback;

import android.slc.base.api.slc.config.ApiConfig;
import android.slc.base.api.slc.converter.SlcEntityErrorException;
import android.slc.base.api.slc.utils.SlcApiUtils;
import android.slc.base.utils.LoadingUtils;
import android.slc.box.commonlibrary.ToastUtils;
import android.slc.box.commonlibrary.compat.SlcResourceUtils;
import android.slc.box.core.provider.ResourceProvider;
import android.slc.box.or.SlcCallbackConfig;
import android.slc.fast.entity.ISlcEntity;
import io.reactivex.rxjava3.annotations.NonNull;
import io.reactivex.rxjava3.core.Observer;
import io.reactivex.rxjava3.disposables.Disposable;
import retrofit2.HttpException;

import java.net.ConnectException;

public abstract class SlcObserver<T> implements Observer<ISlcEntity<T>> {
    protected SlcCallbackConfig mSlcCallbackConfig = SlcCallbackConfig.defSlcCallbackConfig;

    public SlcObserver() {

    }

    public SlcObserver(SlcCallbackConfig slcCallbackConfig) {
        this.mSlcCallbackConfig = slcCallbackConfig;
    }

    @Override
    public void onSubscribe(@NonNull Disposable d) {
        onStart();
    }

    protected void onStart() {
        if (this.mSlcCallbackConfig.isIsShowDialog()) {
            LoadingUtils.showLoadingDialog(String.valueOf(hashCode()), this.mSlcCallbackConfig.getDialogMsg());
        }
    }

    @Override
    public void onNext(ISlcEntity<T> tSlcEntity) {
        onFinish();
        onSucceed(tSlcEntity.getData());
    }

    @Override
    public void onError(Throwable e) {
        e.printStackTrace();
        onFinish();
        int errorCode = 0;
        String errorMessage = e.getMessage();
        if (e instanceof SlcEntityErrorException) {
            errorCode = ((SlcEntityErrorException) e).getErrorCode();
        } else if (e instanceof HttpException) {
            ISlcEntity<T> errorEntity = SlcApiUtils.getMsgByErrorBody((HttpException) e);
            errorCode = errorEntity.getCode();
            errorMessage = errorEntity.getMsg();
        } else if (e instanceof ConnectException) {
            errorCode = ApiConfig.Value.ERROR_REQUEST;
            errorMessage = SlcResourceUtils.getString(ResourceProvider.getInstance().getResourceBundle(),
                    "net_date_connection_failure");
        }
        showToast(errorCode, errorMessage);
        onFailed(errorCode, errorMessage);
    }

    @Override
    public void onComplete() {

    }

    protected void onFinish() {
        if (mSlcCallbackConfig.isIsShowDialog() && mSlcCallbackConfig.isIsAutoDismissDialog()) {
            dismissDialog();
        }
    }

    protected void dismissDialog() {
        LoadingUtils.dismissLoadingDialog(String.valueOf(hashCode()));
    }

    /**
     * 显示toast
     *
     * @param code
     * @param msg
     */
    protected void showToast(int code, String msg) {

        if (mSlcCallbackConfig.isIsShowToast()) {
            switch (code) {
                case ApiConfig.Value.ERROR_REQUEST:
                case ApiConfig.Value.NORMAL_UNAUTHORIZED:
                case ApiConfig.Value.SERVER_ERROR:
                case ApiConfig.Value.NOT_IMPLEMENTED:
                case ApiConfig.Value.RESULT_UPLOAD_FAILURE:
                    ToastUtils.showShort(msg);
                    break;
                default:
                    ToastUtils.showShort(mSlcCallbackConfig.getToastRes());
                    break;
            }
        }
    }

    protected abstract void onSucceed(T data);

    protected abstract void onFailed(int errorCode, String errorMessage);
}
